package utilities;


import java.util.*;
import java.io.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.*;

public class EngineCommander implements Commander{
	
	private BufferedWriter log = null;
	private String name;
	private Engine e;
	private List workQueue;
	private Map actionDefs;
	private String className;
	private int sleeps = 1000;
	private String note;
	private String configFile;
	private String appDir;
	private Document doc;


	private  String outFileName=null;
	private  String scanDelay=null; 
	private  String debugLevel=null;
	private  String active = null;
	private  String engineAppDir;
	private String config1=null;
	private String config2=null;
	private String config3=null;
	
	private Object configData;
	              
	public String getName()
	{
		return name;
	}
	public EngineCommander(String name, String note, String appDir, String configFile)
	{
		this.name = name;
		this.configFile = configFile;
		this.note = note;		
		this.appDir = appDir;

		
		this.processConfig();
		
		//create the log file.
		try {
			log = new BufferedWriter(new FileWriter(outFileName));
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}		
		this.loadClassInstance();
						
		e.newEngine(name, log, workQueue, doc, 
				Integer.valueOf(scanDelay).intValue(),Integer.valueOf(debugLevel).intValue(),this);
	    e.start();		
		
	    try {
			log.write(name + " started\n");
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	   
	}
	public void close()
	{
		
		try {
			e.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
	
	public String getAppEngineDir()
	{
		return engineAppDir;
	}
	
	
	public String getConfig1()
	{
		return config1;
	}
	public String getConfig2()
	{
		return config2;
	}
	public String getConfig3()
	{
		return config3;
	}
	
	
	private void loadClassInstance()
	{
	    ClassLoader classLoader = EngineCommander.class.getClassLoader();	    
	    try {
	        Class aClass = classLoader.loadClass(className);

	        e = (Engine) aClass.newInstance();

	    } catch (Exception e) {
	        e.printStackTrace();
	    }	
	}
	

	
	public void restart()
	{
		this.kill();
		processConfig();

		e.newEngine(name, log, workQueue, doc, 
				Integer.valueOf(scanDelay).intValue(),Integer.valueOf(debugLevel).intValue(),this);
		try {
			log.write(name + " restarted\n");
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	    e.start();		
		
	}
	
	public void deActivate()
	{
		e.deActivate();
	}
	public void activate()
	{
		e.activate();
	}
	
	public void kill()
	{
		e.destroy();
		e=null;
	}
	public int getQueueCnt()
	{
		return workQueue.size();		
	}
	public void addAction(Action action)
	{
		workQueue.add(action);
		try {
			log.write("Action queued: " + action.getActionDef().getName() +"\n");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void clearQueue()
	{
		workQueue.clear();
	}
	public ActionDef getActionDefByName(String name)
	{
		if (actionDefs.containsKey(name)) return (ActionDef) actionDefs.get(name);
		
		return null;
	}
	
	public void processConfig()
	{
		sleeps = 1000;
		workQueue = new ArrayList();		
		
		//create config data.
		String fName = appDir + this.configFile;
		
		  try {
		  File file = new File(fName);
		  
		  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		  DocumentBuilder db = dbf.newDocumentBuilder();
		  Document doc = db.parse(file);
		  doc.getDocumentElement().normalize();
		  		  
		  /*
		   * Parameters section
		   */
		  NodeList nodeLst = doc.getElementsByTagName("params");  
			
		 

		  nodeLst = doc.getElementsByTagName("outFileName");
		  for (int s = 0; s < nodeLst.getLength(); s++) {
			  	Node tn = nodeLst.item(s);
			  	outFileName = tn.getChildNodes().item(0).getNodeValue();
			  	//tn.getChildNodes().item(0).setNodeValue("TestOutValue");
			  	break;
		  }
		  
		  nodeLst = doc.getElementsByTagName("appDir");
		  for (int s = 0; s < nodeLst.getLength(); s++) {
			  	Node tn = nodeLst.item(s);
			  	engineAppDir = tn.getChildNodes().item(0).getNodeValue();
			  	//tn.getChildNodes().item(0).setNodeValue("TestOutValue");
			  	break;
		  }
		  
		  nodeLst = doc.getElementsByTagName("scanDelay");
		  for (int s = 0; s < nodeLst.getLength(); s++) {
			  scanDelay = nodeLst.item(s).getChildNodes().item(0).getNodeValue();
			    break;
		  }
		  nodeLst = doc.getElementsByTagName("debugLevel");
		  for (int s = 0; s < nodeLst.getLength(); s++) {
			  debugLevel = nodeLst.item(s).getChildNodes().item(0).getNodeValue();
			    break;
		  }
		  nodeLst = doc.getElementsByTagName("active");
		  for (int s = 0; s < nodeLst.getLength(); s++) {
			  active = nodeLst.item(s).getChildNodes().item(0).getNodeValue();
			    break;
		  } 
		  
		  nodeLst = doc.getElementsByTagName("className");
		  for (int s = 0; s < nodeLst.getLength(); s++) {
			  className = nodeLst.item(s).getChildNodes().item(0).getNodeValue();
			    break;
		  } 
		  
		  nodeLst = doc.getElementsByTagName("config1");
		  for (int s = 0; s < nodeLst.getLength(); s++) {
			  config1 = nodeLst.item(s).getChildNodes().item(0).getNodeValue();
			    break;
		  } 
		  nodeLst = doc.getElementsByTagName("config2");
		  for (int s = 0; s < nodeLst.getLength(); s++) {
			  config2 = nodeLst.item(s).getChildNodes().item(0).getNodeValue();
			    break;
		  } 
		  nodeLst = doc.getElementsByTagName("config3");
		  for (int s = 0; s < nodeLst.getLength(); s++) {
			  config3 = nodeLst.item(s).getChildNodes().item(0).getNodeValue();
			    break;
		  } 
		  
		  
		  
		  //load actions.....
		  actionDefs = new TreeMap();
		  nodeLst = doc.getElementsByTagName("action");
		  String an = null;
		  String am = null;
		  for (int s = 0; s < nodeLst.getLength(); s++) {
		
			  Node fstNode2 = nodeLst.item(s);
			  Element fstElmnt2 = (Element) fstNode2;
			  
			  NodeList nodeLst2 = fstElmnt2.getElementsByTagName("name");
			  for (int s2 = 0; s2 < nodeLst.getLength(); s2++) {
				  an = nodeLst2.item(s2).getChildNodes().item(0).getNodeValue();
				    break;
			  } 			  
			  nodeLst2 = fstElmnt2.getElementsByTagName("method");
			  for (int s2 = 0; s2 < nodeLst.getLength(); s2++) {
				  am = nodeLst2.item(s2).getChildNodes().item(0).getNodeValue();
				    break;
			  } 			  
			  nodeLst2 = fstElmnt2.getElementsByTagName("arg");		  
			 //create action
			  ActionDef a = new ActionDef(an, am, nodeLst2);
			  actionDefs.put(an, a);
		  } 
		  
		  am = "stop";
		  
		  
		  
		  
		  } catch (Exception e) {
		    e.printStackTrace();
		  }
		  
		  
		  
		  
		 		
	}
	
	
}